package com.ruoyi.tracker.service.Impl;

import com.ruoyi.common.core.web.domain.AjaxResult;
import com.ruoyi.tracker.vo.LocationQueryVo;
import org.influxdb.InfluxDB;
import org.influxdb.dto.Point;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.springframework.data.geo.*;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.tracker.domain.VehicleLocation;
import com.ruoyi.tracker.mapper.VehicleLocationMapper;
import com.ruoyi.tracker.service.VehicleLocationService;
@Service
public class VehicleLocationServiceImpl extends ServiceImpl<VehicleLocationMapper, VehicleLocation> implements VehicleLocationService{
    @Autowired
    private InfluxDB influxDB;
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Autowired
    private VehicleLocationMapper vehicleLocationMapper;
    @Override
    public HashMap<String, Object> report(VehicleLocation vehicleLocation) {
        try {
            // 统一表名，确保与查询一致
            Point build = Point.measurement("vehicle_location")
                    .tag("vehicle_id", vehicleLocation.getVehicleId())
                    .tag("plate_number", vehicleLocation.getPlateNumber())
                    .addField("vehicle_longitude", vehicleLocation.getVehicleLongitude())
                    .addField("vehicle_latitude", vehicleLocation.getVehicleLatitude())
                    .addField("vehicle_speed", vehicleLocation.getVehicleSpeed())
                    .time(System.currentTimeMillis(), TimeUnit.MICROSECONDS)
                    .build();
            // 添加日志记录，便于调试
            System.out.println("Writing data to InfluxDB: " + build);
            // 写入InfluxDB
            influxDB.write(build);
            //存入redis中
            String key = "vehicle_location:" + vehicleLocation.getPlateNumber();
            redisTemplate.opsForGeo().add(key, new org.springframework.data.geo.Point(
                    vehicleLocation.getVehicleLongitude(),
                    vehicleLocation.getVehicleLatitude()),
                    vehicleLocation.getPlateNumber());
            //设置过期时间
            redisTemplate.expire(key, 1, TimeUnit.MINUTES);
            return new HashMap<String, Object>() {{
                put("status", "success");
                put("message", "Data written successfully");
            }};
        } catch (Exception e) {
            log.error("Error writing data to InfluxDB", e);
            return new HashMap<String, Object>() {{
                put("status", "error");
                put("message", "Failed to write data to InfluxDB");
            }};
        }
    }

    @Override
    public HashMap<String, Object> selectQuery(Double vehicleLatitude, Double vehicleLongitude) {
        GeoOperations<String, String> stringStringGeoOperations = redisTemplate.opsForGeo();
        org.springframework.data.geo.Point point = new org.springframework.data.geo.Point(vehicleLongitude, vehicleLatitude);
        Distance distance = new Distance(5, Metrics.KILOMETERS);
        Circle circle = new Circle(point, distance);
        RedisGeoCommands.GeoRadiusCommandArgs limit = RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs()
                .includeDistance()
                .includeCoordinates()
                .sortAscending()
                .limit(10);
        GeoResults<RedisGeoCommands.GeoLocation<String>> radius = stringStringGeoOperations.radius("vehicle_location:", circle, limit);
        for (GeoResult<RedisGeoCommands.GeoLocation<String>> geoLocationGeoResult : radius) {
            RedisGeoCommands.GeoLocation<String> location = geoLocationGeoResult.getContent();
            System.out.println("Plate Number: " + location.getName());
            System.out.println("Distance: " + geoLocationGeoResult.getDistance().getValue() + " km");
            System.out.println("Coordinates: " + location.getPoint().getX() + ", " + location.getPoint().getY());
            System.out.println("----------------------------------------");
        }
        return AjaxResult.success("查询成功", radius);
    }
}
